use chrono::{DateTime, Local};
use serde::{Serialize, Deserialize};
use serde_repr::{Deserialize_repr, Serialize_repr};
use crate::db::pojo::pojo::{ImUser, ImUserStatus};
use crate::business::websocket::dto::json_serialize:: {date_time_serde, date_time_serde_null};

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LoginReq {

    #[serde(rename = "userId")]
    pub user_id: String,
    pub password: String,

    #[serde(rename = "machineCode")]
    pub machine_code: String,

    #[serde(rename = "tenantCode")]
    pub tenant_code: String,

    #[serde(rename = "terminalType")]
    pub terminal_type: TerminalType,

    #[serde(rename = "createDateTime", with = "date_time_serde")]
    pub create_date_time: DateTime<Local>,

    #[serde(rename = "localSeq")]
    pub local_seq: String,
    // pub wight: u32,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct LoginTokenReq {
    #[serde(rename = "userId")]
    pub user_id: String,
    pub token: String,
    #[serde(rename = "machineCode")]
    pub machine_code: String,

    #[serde(rename = "tenantCode")]
    pub tenant_code: String,

    #[serde(rename = "terminalType")]
    pub terminal_type: TerminalType,

    #[serde(rename = "createDateTime", with = "date_time_serde")]
    pub create_date_time: DateTime<Local>,

    #[serde(rename = "localSeq")]
    pub local_seq: String,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct Reconnection {
    #[serde(rename = "authToken")]
    pub auth_token: String,

    #[serde(rename = "tenantCode")]
    pub tenant_code: String,

    #[serde(rename = "terminalType")]
    pub terminal_type: TerminalType,

    #[serde(rename = "createDateTime", with = "date_time_serde")]
    pub create_date_time: DateTime<Local>,

    #[serde(rename = "localSeq")]
    pub local_seq: String,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct UserInfoListReq {
    #[serde(rename = "createDateTime", with = "date_time_serde")]
    pub create_date_time: DateTime<Local>,

    #[serde(rename = "localSeq")]
    pub local_seq: String,

    #[serde(rename = "startUserId")]
    pub start_user_id: Option<String>,

    #[serde(rename = "pageSize")]
    pub page_size: u32,

    #[serde(rename = "startDate", with = "date_time_serde_null")]
    pub start_date: Option<DateTime<Local>>,

    #[serde(rename = "isLatestChange")]
    pub is_latest_change: bool
}

#[derive(Debug, Serialize, Deserialize)]
pub struct UserInfoItemList {

    #[serde(rename = "userInfoItemList")]
    pub user_info_item_list: Vec<UserInfoItem>,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct UserInfoItem {

    #[serde(rename = "userId")]
    pub user_id: String,

    #[serde(rename = "userName")]
    pub user_name: String,
    pub mobile: Option<String>,

    #[serde(rename = "headImg")]
    pub head_img: Option<String>,
    pub motto: Option<String>,
    pub sex: SexEnum,

    #[serde(rename = "firstLetter")]
    pub first_letter: Option<String>,

    #[serde(rename = "departmentCode")]
    pub department_code: Option<String>,

    #[serde(rename = "otherDepartmentCodes")]
    pub other_department_codes: Option<String>,
    pub status: EnableType,
}

#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct LoginResp {
    #[serde(rename = "successDataTime", with = "date_time_serde")]
    pub success_data_time: DateTime<Local>,

    #[serde(rename = "localSeq")]
    pub local_seq: String,
    pub coder: i16,
    #[serde(rename = "otherInfo")]
    pub other_info: Option<String>,
    #[serde(rename = "userId")]
    pub user_id: String,
    #[serde(rename = "tenantCode")]
    pub tenant_code: String,

    #[serde(rename = "serverDateTime", with = "date_time_serde")]
    pub server_date_time: DateTime<Local>,

    #[serde(rename = "authToken")]
    pub auth_token: String,
    pub token: String,
    #[serde(rename = "authCode")]
    pub auth_code: i32,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum TerminalType {
    #[serde(rename = "pc")]
    Pc,
    #[serde(rename = "android")]
    Android,
    #[serde(rename = "ios")]
    Ios,
    #[serde(rename = "pad")]
    Pad,
    #[serde(rename = "ipad")]
    Ipad,
    #[serde(rename = "web")]
    Web,
    #[serde(rename = "hm")]
    Hm,
}

#[derive(Debug, Clone, Serialize_repr, Deserialize_repr, PartialEq)]
#[repr(u8)]
pub enum SexEnum {
    Male = 1,
    Female = 2,
}

#[derive(Debug, Clone, Serialize_repr, Deserialize_repr, PartialEq)]
#[repr(u8)]
pub enum EnableType {
    Enabled = 1,
    Disabled = 2,
}

impl Into<ImUser> for UserInfoItem {
    fn into(self) -> ImUser {
        ImUser {
            id: None,
            user_id: self.user_id,
            user_name: self.user_name,
            mobile: self.mobile,
            motto: self.motto,
            head_img: self.head_img,
            description: None,
            department_code: self.department_code,
            other_department_codes: self.other_department_codes,
            status: self.status.into(),
            sex: self.sex,
            ext1: None,
            ext2: None,
            first_letter: self.first_letter,
            create_date_time: Local::now(),
            update_date_time: Local::now(),
        }
    }
}

impl From<EnableType> for ImUserStatus {
    fn from(value: EnableType) -> Self {
        match value {
            EnableType::Enabled => {ImUserStatus::Enable}
            EnableType::Disabled => {ImUserStatus::Disable }
        }
    }
}


